/*
 * Copyright (C) 2008 Alessandro Sivieri <alessandro.sivieri@chimera-bellerofonte.eu>.
 *
 *  This file is part of Daex.
 *
 *  Daex is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Foobar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 */
package eu.chimera_bellerofonte.tesi;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.DateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.Properties;
import java.util.logging.Level;

/**
 * <p>Classe di definizione delle proprieta' di configurazione
 * salvate e caricate dal sistema. Crea un'istanza statica
 * caricata dal file di configurazione se salvato precedentemente,
 * altrimenti costruisce alcune proprieta' di default.</p>
 * <p>Le proprieta' di default sono 4:
 * <ul>
 * <li>thesis.directory.temp: la directory indicata come temporanea
 * per i files intermedi; il valore di default punta alla directory
 * temporanea di sistema (su sistema Unix tipicamente /tmp)</li>
 * <li>thesis.directory.out: la directory di output per i files finali;
 * il valore di default punta alla directory dell'utente corrente</li>
 * <li>thesis.lastopendir: l'ultima directory da cui si sono aperti files
 * del programma; di default la directory home dell'utente</li>
 * <li>thesis.extension: l'estensione dei files salvati dal programma;
 * vale ".daex" (read only)</li>
 * </ul>
 * </p>
 * 
 * @author Sivieri Alessandro
 * @author Vitucci Nicola
 * @version 16/mag/07
 */
public class DaexProperties
{
	/**
	 * Prefisso automatico di tutte le proprieta' salvate
	 * nel file.
	 */
	public static final String PREFIX="daex.";
	/**
	 * Directory del file per le configurazioni.
	 */
	public static final String CONFIGDIR=System.getProperty("user.home")+File.separator+".daex"+File.separator;
	/**
	 * Nome del file in cui vengono salvate tutte le proprieta'.
	 */
	public static final String CONFIGNAME="config.xml";

	private static Properties props=null;
	// da settare solo se si vuole forzare la riscrittura del file
	// delle proprieta'
	private static boolean recreate=false;
	
	public static void init()
	{
		props=new Properties();
		if(recreate)
		{
			setDefaults();
		}
		else
		{
			try
			{
				load();
				// verifica della presenza delle proprieta' fondamentali
				if (getProperty("directory.temp")==null ||
					getProperty("directory.out")==null ||
					getProperty("lastopendir")==null ||
					getProperty("extension")==null)
				{
					setDefaults();
				}
			}
			catch (Exception e)
			{
				DaexLogger.getDaexLogger().log(Level.WARNING, "Impossibile caricare il file di configurazione da "+CONFIGNAME, e);
				setDefaults();
			}
		}
		Runtime.getRuntime().addShutdownHook(new Thread()
		{
			public void run()
			{
				try
				{
					File dir=new File(CONFIGDIR);
					if(!dir.isDirectory())
					{
						dir.mkdir();
					}
					DaexProperties.store("Dvd Audio EXtractor - salvato il "+DateFormat.getDateInstance(DateFormat.LONG).format(new Date()));
					DaexLogger.getDaexLogger().info("File di configurazione correttamente salvato");
				}
				catch (IOException e)
				{
					DaexLogger.getDaexLogger().log(Level.WARNING, "Impossibile salvare la configurazione su "+CONFIGNAME, e);
				}
			}
		});
	}
	
	/**
	 * Aggiunta di una proprieta': il nome non necessita del prefisso
	 * che verra' aggiunto di default.
	 * 
	 * @param name il nome della proprieta' (cui verra' aggiunto il prefisso specifico di questa applicazione)
	 * @param value il valore da assegnare a tale proprieta'
	 */
	public static void addProperty(String name, String value)
	{
		if(!"extension".equals( name ))
		{
			props.setProperty(PREFIX+name, value);
		}
	}
	
	/**
	 * Metodo per ottenere il valore di una proprieta' salvato in precendenza.
	 * 
	 * @param name il nome della proprieta' (senza il prefisso)
	 * @return il valore della proprieta', se esiste
	 */
	public static String getProperty(String name)
	{
		return props.getProperty(PREFIX+name);
	}
	
	/**
	 * Metodo per sapere se la chiave specificata e' una proprieta'
	 * registrata nel sistema.
	 * 
	 * @param name il nome della chiave
	 * @return vero se esiste tale chiave, falso altrimenti
	 */
	public static boolean isProperty(String name)
	{
		return props.getProperty(name)!=null;
	}
	
	/**
	 * Setta i valori di default di alcune delle proprieta';
	 * vedere la descrizione iniziale per la definizione di queste.
	 * <br>
	 * Non passa per l'addProperty() qui definito poiche' questo
	 * inibisce la modifica di alcune opzioni. 
	 */
	public static void setDefaults()
	{
		props.clear();
		if(System.getProperty("os.name").contains("Windows"))
			props.setProperty(PREFIX+"directory.temp", "tmp");
		else
			props.setProperty(PREFIX+"directory.temp", System.getProperty("java.io.tmpdir")+File.separator+"daex");
		props.setProperty(PREFIX+"directory.out", System.getProperty("user.dir")+File.separator+"Musica");
		props.setProperty(PREFIX+"lastopendir", System.getProperty("user.dir"));
		props.setProperty(PREFIX+"extension", ".daex");

	}
	
	/**
	 * Salvataggio delle proprieta' sul file XML di default.
	 * Ad ogni uscita dall'applicazione viene invocato tale
	 * metodo.
	 * 
	 * @param comment un commento da inserire nel sistema
	 * @throws IOException eccezione lanciata in caso di problemi
	 */
	public static void store(String comment) throws IOException
	{
		File f=new File(CONFIGDIR);
		if(!f.exists())
			f.mkdirs();
		OutputStream out=new FileOutputStream(CONFIGDIR+CONFIGNAME);
		props.storeToXML(out, comment);
		DaexLogger.getDaexLogger().info("Salvataggio delle proprieta' correttamente eseguito.");
	}
	
	/**
	 * Metodo per il caricamento delle proprieta' dal file XML di
	 * default.
	 * 
	 * @throws InvalidDaexPropertiesFormatException eccezione lanciata se il file delle proprieta' non corrisponde
	 * @throws IOException eccezione lanciata in caso di problemi
	 */
	public static void load() throws InvalidDaexPropertiesFormatException, IOException
	{
		InputStream in=new FileInputStream(CONFIGDIR+CONFIGNAME);
		props.loadFromXML(in);
		Enumeration<?> keys=props.propertyNames();
		while(keys.hasMoreElements())
		{
			if(!((String) keys.nextElement()).startsWith(PREFIX))
			{
				throw new InvalidDaexPropertiesFormatException("Problema con la configurazione");
			}
		}
		DaexLogger.getDaexLogger().info("File delle proprieta' correttamente caricato.");
	}
}
